package com.mamingchao.concurrent.threads_communication3;

import java.util.ArrayList;
import java.util.List;

/**
 * 使用Object类的wait() 和 notify() 方法
 * Object类提供了线程间通信的方法：wait()、notify()、notifyaAl()，
 * 它们是多线程通信的基础，而这种实现方式的思想自然是线程间通信。
 *
 *  wait和 notify必须配合synchronized使用，wait方法释放锁，notify方法不释放锁
 *  所以，虽然a运行到第5个元素的时候，notify 线程b了，但是没有释放锁
 *  线程b 也就是从锁的等待池被叫到锁池里，从等待状态变成锁 竞争状态
 *
 *  这种实现也必须是线程b先运行
 *
 * Created by mamingchao on 2020/9/19.
 */
public class WithObjectNotifyWait {


    static List<Integer> lists = new ArrayList<>();

    public static void main(String[] args) {
        Object lock = new Object();

        Thread b = new Thread( ()->{
            while (true){
                System.out.println(123);
                synchronized(lock) {
                    try {
                        lock.wait();
                        System.out.println("线程B收到通知，开始执行自己的业务...");
                        //这种方式的解决办法：加上下面这句话
                        lock.notify();
                        break;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        });

        Thread a = new Thread(() -> {

            synchronized (lock) {
                for (int i = 0; i < 10; i++) {
                    lists.add(i);
                    System.out.println(i);
                    if (i == 5){
                        lock.notify();

                        //因为notify 不释放锁，这里加上 lock.wait 让出来锁
                        //这种方式的解决办法：加上下面这句话
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
//                    try {
//                        TimeUnit.MILLISECONDS.sleep(1000);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
                }
            }

        });


        b.start();
        a.start();
    }
}
